package main

import (
	"errhandling/fileListeningServer/fileListening"
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
)

// 可以给用户看到错误  userError 接口
type userError interface {
	error            // 给系统
	Message() string // 给用户
}

// 函数类型是handler里面函数,所以可以将下面 errWrapper套在外面
type appHandler func(writer http.ResponseWriter, request *http.Request) error // 返回error

// 返回error包装后返回 func(http.ResponseWriter, *http.Request)
// 处理错误
/**
 * 输入 输出都是函数
 */
func errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {

	return func(writer http.ResponseWriter, request *http.Request) { // 服务器处理的函数
		// http://localhost:8888/l11
		defer func() { // 进行recover
			if r := recover(); r != nil { // r == nil 是没错的
				log.Printf("AQIE Panic: %v", r)
				http.Error(writer,
					http.StatusText(http.StatusInternalServerError),
					http.StatusInternalServerError)
			}
		}()
		err := handler(writer, request)
		if err != nil {
			log.Printf("Error occurred "+
				"handling request: %s",
				err.Error())

			// user error
			if userErr, ok := err.(userError); ok {
				http.Error(writer,
					userErr.Message(),
					http.StatusBadRequest)
				return
			}

			// system error
			code := http.StatusOK
			switch {
			case os.IsNotExist(err):
				code = http.StatusNotFound
			case os.IsPermission(err):
				code = http.StatusForbidden
			default:
				code = http.StatusInternalServerError

			}
			http.Error(writer, http.StatusText(code), code)
		}
	}
}

// url 打文件地址显示文件内容
// http://localhost:8888/list/hello.go
func main() {
	http.HandleFunc("/", // /list/ 虚拟路径，如果改成 /
		errWrapper(fileListening.HandleFileList))
	err := http.ListenAndServe(":8888", nil)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("server listen on 8888")
	}
}
